﻿using System;
using System.Collections.Generic;
using System.Linq;
using MIAP.DataAccess.Interfaces;
using MIAP.DataAccess.SqlServer.Model;
using MIAP.Entidades;
using MIAP.Entidades.Enums;

namespace MIAP.DataAccess.Implementaciones.SQL
{
    /// <summary>
    /// Clase de las operaciones de acceso a datos para él módulo de proyectos.
    /// </summary>
    public class ProyectosDao : IProyectosDao
    {
        /// <summary>
        /// Obtiene todos los proyectos.
        /// </summary>
        /// <returns>Lista con todos los usuarios.</returns>
        IList<ProyectoInfo> IProyectosDao.GetProyectos()
        {
            return GetProyectos(null, null);
        }

        /// <summary>
        /// Obtiene todos los Proyectos que cumplan con el nombre y o estatus.
        /// </summary>
        /// <param name="nombreProyecto">Nombre del proyecto por el cual filtraremos (comando contain) mandar null si no se requiere busqueda por este campo </param>
        /// <param name="estatusActivo">True (Activo), False (Inactivo) mandar null si no se requiere este campo</param>
        /// <returns>Lista con los usuarios con el filtro realizado</returns>
        public IList<ProyectoInfo> GetProyectos(string nombreProyecto, bool? estatusActivo)
        {
            IList<ProyectoInfo> result;

            using (var context = new MIAPDBEntities())
            {
                var query = from proyecto in context.MIAP_PROYECTO
                            where (String.IsNullOrEmpty(nombreProyecto)||proyecto.NOMBRE.Contains(nombreProyecto))&&
                            (estatusActivo==null|| proyecto.ACTIVO==estatusActivo)
                            select new ProyectoInfo
                            {
                                IDProyecto = proyecto.ID_PROYECTO,
                                Descripcion = proyecto.DESCRIPCION,
                                Estatus = proyecto.ACTIVO?"Activo":"Inactivo",
                                NombreProyecto = proyecto.NOMBRE,
                                FechaActualizacion = proyecto.FECHA_ACTUALIZACION,
                                FechaCreacion = proyecto.FECHA_CREACION,    
                                PaqueteCarga = proyecto.PAQUETE_CARGA,
                                PeriodoCarga = new PeriodoInfo
                                {
                                    IdentificadorPeriodo = proyecto.MIAP_PERIODO_CARGA.ID_PERIODO_CARGA,
                                    NombrePeriodo = proyecto.MIAP_PERIODO_CARGA.NOMBRE,
                                    TipoPeriodo = TipoPeriodo.Carga
                                },
                                PeriodoInformacion = new PeriodoInfo
                                {
                                    IdentificadorPeriodo = proyecto.MIAP_PERIODO_INFORMACION.ID_PERIODO_INFORMACION,
                                    NombrePeriodo = proyecto.MIAP_PERIODO_INFORMACION.NOMBRE,
                                    TipoPeriodo = TipoPeriodo.Informacion
                                }
                            };
                result = query.ToList();
            }

            return result; 
        }

        /// <summary>
        /// Cambia el estatus del proyecto a activo o inactivo.
        /// </summary>
        /// <param name="idProyecto">Es el id del proyecto del cual se cambiará el estatus.</param>
        /// <param name="estatusRegistro">Estatus a colocar True (Activo), False (Inactivo)</param>
        void IProyectosDao.ChangeEstatusProyecto(int idProyecto, bool estatusRegistro)
        {
            using (var context = new MIAPDBEntities())
            {
                var query = (from proyecto in context.MIAP_PROYECTO
                             where proyecto.ID_PROYECTO == idProyecto
                             select proyecto).SingleOrDefault();
                if (query == null) return;

                query.ACTIVO = estatusRegistro;
                context.SaveChanges();
            }
        }

        /// <summary>
        /// Obtiene la información de un determinado proyecto.
        /// </summary>
        /// <param name="idProyecto">Es el id del proyecto del que se desea obtener la información.</param>
        /// <returns>Información general del usuario.</returns>
        ProyectoInfo IProyectosDao.GetProyectoById(int idProyecto)
        {
            ProyectoInfo result;

            using (var context = new MIAPDBEntities())
            {
                var query = (from proyecto in context.MIAP_PROYECTO
                             where proyecto.ID_PROYECTO==idProyecto
                            select new ProyectoInfo
                            {
                                IDProyecto = proyecto.ID_PROYECTO,
                                Descripcion = proyecto.DESCRIPCION,
                                Estatus = proyecto.ACTIVO ? "Activo" : "Inactivo",
                                NombreProyecto = proyecto.NOMBRE,
                                FechaActualizacion = proyecto.FECHA_ACTUALIZACION,
                                FechaCreacion = proyecto.FECHA_CREACION,
                                PaqueteCarga = proyecto.PAQUETE_CARGA,
                                PeriodoCarga = new PeriodoInfo
                                {
                                    IdentificadorPeriodo = proyecto.MIAP_PERIODO_CARGA.ID_PERIODO_CARGA,
                                    NombrePeriodo = proyecto.MIAP_PERIODO_CARGA.NOMBRE,
                                    TipoPeriodo = TipoPeriodo.Carga
                                },
                                PeriodoInformacion = new PeriodoInfo
                                {
                                    IdentificadorPeriodo = proyecto.MIAP_PERIODO_INFORMACION.ID_PERIODO_INFORMACION,
                                    NombrePeriodo = proyecto.MIAP_PERIODO_INFORMACION.NOMBRE,
                                    TipoPeriodo = TipoPeriodo.Informacion
                                }
                            }).SingleOrDefault();
                result = query;
            }
            return result;
        }

        /// <summary>
        /// Agrega un nuevo proyecto.
        /// </summary>
        /// <param name="proyecto">Es el proyecto que será agregado.</param>
        /// <param name="user">Usuario que esta agregando la información.</param>
        void IProyectosDao.AddNewProyecto(ProyectoInfo proyecto, string user)
        {
            using (var context = new MIAPDBEntities())
            {
                var miapProyecto= new MIAP_PROYECTO
                    {
                        ID_PERIODO_CARGA = proyecto.PeriodoCarga.IdentificadorPeriodo,
                        ID_PERIODO_INFORMACION = proyecto.PeriodoInformacion.IdentificadorPeriodo,
                        ACTIVO = proyecto.Estatus.ToUpper().Trim()=="ACTIVO",
                        NOMBRE = proyecto.NombreProyecto,
                        PAQUETE_CARGA = proyecto.PaqueteCarga,
                        USUARIO_CREACION = user,
                        USUARIO_ACTUALIZACION = user,
                        FECHA_ACTUALIZACION = DateTime.Now,
                        FECHA_CREACION = DateTime.Now,
                        DESCRIPCION = proyecto.Descripcion
                    };

                context.MIAP_PROYECTO.Add(miapProyecto);

                context.SaveChanges();
            }
        }

        /// <summary>
        /// Modifica la información de un proyecto .
        /// </summary>
        /// <param name="proyecto">Es el proyecto al que se le modificará la información.</param>
        /// <param name="user">Es el usuario que esta modificando la información.</param>
        void IProyectosDao.EditProyecto(ProyectoInfo proyecto, string user)
        {
            using (var context = new MIAPDBEntities())
            {
                var query = (from proy in context.MIAP_PROYECTO
                             where proy.ID_PROYECTO == proyecto.IDProyecto
                             select proy).SingleOrDefault();
                if (query == null) return;

                query.ACTIVO = proyecto.Estatus.ToUpper().Trim() == "ACTIVO";
                query.NOMBRE = proyecto.NombreProyecto;
                query.DESCRIPCION = proyecto.Descripcion;
                query.PAQUETE_CARGA = proyecto.PaqueteCarga;
                query.ID_PERIODO_CARGA = proyecto.PeriodoCarga.IdentificadorPeriodo;
                query.ID_PERIODO_INFORMACION = proyecto.PeriodoInformacion.IdentificadorPeriodo;
                query.FECHA_ACTUALIZACION = DateTime.Now;
                query.USUARIO_ACTUALIZACION = user;
                context.SaveChanges();
            }
        }

        /// <summary>
        /// Obtiene el id y la descripción de todos los proyectos.
        /// </summary>
        /// <returns>Lista con ids y descripciones de todos los proyectos.</returns>
        public IList<CatalogoInfo> GetCatalogProyecto()
        {
            List<CatalogoInfo> result;

            using(var context = new MIAPDBEntities())
            {
                var query = from proyecto in context.MIAP_PROYECTO
                            where proyecto.ACTIVO == true
                            select new CatalogoInfo
                            {
                                IdItem = proyecto.ID_PROYECTO,
                                Descripcion = proyecto.NOMBRE
                            };
                result = query.ToList();
            }

            return result;
        }

        /// <summary>
        /// Verifica la existencia del proyecto.
        /// </summary>
        /// <param name="nombreProyecto">Nombre del proyecto que se desea agregar.</param>
        /// <returns>Indicador de si el proyecto existe o no.</returns>
        public bool VerifyExistProyecto(string nombreProyecto)
        {
            using (var context = new MIAPDBEntities())
            {
                var query = from proyecto in context.MIAP_PROYECTO
                            where (proyecto.NOMBRE.Trim().ToLower() == nombreProyecto)
                            select proyecto;

                MIAP_PROYECTO proyectoExistente = query.SingleOrDefault();

                if (proyectoExistente != null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
}
